package com.kelab.dify.service;

import com.kelab.dify.config.DifyConfig;
import com.kelab.dify.exception.DifyException;
import com.kelab.dify.service.base.BaseService;
import com.fasterxml.jackson.databind.ObjectMapper;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

/**
 * 音频服务类
 * 提供Audio API的所有功能，包括文本转语音(TTS)和语音转文本(STT)
 * 
 * @author kelab
 * @version 1.0
 */
public class AudioService extends BaseService {
    
    private static final Logger logger = LoggerFactory.getLogger(AudioService.class);
    
    private static final String TEXT_TO_AUDIO_ENDPOINT = "text-to-audio";
    private static final String AUDIO_TO_TEXT_ENDPOINT = "audio-to-text";
    
    /**
     * 构造函数
     * 
     * @param httpClient HTTP客户端
     * @param objectMapper JSON映射器
     * @param config 配置信息
     */
    public AudioService(OkHttpClient httpClient, ObjectMapper objectMapper, DifyConfig config) {
        super(httpClient, objectMapper, config);
    }
    
    /**
     * 文本转语音
     * 
     * @param text 要转换的文本
     * @param user 用户标识
     * @param voice 语音类型（可选）
     * @param streaming 是否流式输出（可选）
     * @return 音频响应
     * @throws DifyException 如果请求失败
     */
    public AudioResponse textToAudio(String text, String user, String voice, Boolean streaming) throws DifyException {
        StringBuilder jsonBuilder = new StringBuilder();
        jsonBuilder.append("{");
        jsonBuilder.append("\"text\":\"").append(text.replace("\"", "\\\"")).append("\",");
        jsonBuilder.append("\"user\":\"").append(user).append("\"");
        
        if (voice != null && !voice.isEmpty()) {
            jsonBuilder.append(",\"voice\":\"").append(voice).append("\"");
        }
        if (streaming != null) {
            jsonBuilder.append(",\"streaming\":").append(streaming);
        }
        jsonBuilder.append("}");
        
        RequestBody body = RequestBody.create(jsonBuilder.toString(), JSON_MEDIA_TYPE);
        
        Request request = new Request.Builder()
                .url(config.getFullUrl(TEXT_TO_AUDIO_ENDPOINT))
                .post(body)
                .addHeader("Authorization", config.getAuthorizationHeader())
                .addHeader("Content-Type", "application/json")
                .build();
        
        try (Response response = httpClient.newCall(request).execute()) {
            return handleResponse(response, AudioResponse.class);
        } catch (IOException e) {
            throw new DifyException("Failed to convert text to audio", e);
        }
    }
    
    /**
     * 语音转文本
     * 
     * @param audioFile 音频文件
     * @param user 用户标识
     * @return 文本响应
     * @throws DifyException 如果请求失败
     */
    public TextResponse audioToText(java.io.File audioFile, String user) throws DifyException {
        MultipartBody body = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", audioFile.getName(),
                        RequestBody.create(audioFile, MediaType.parse("audio/*")))
                .addFormDataPart("user", user)
                .build();
        
        Request request = new Request.Builder()
                .url(config.getFullUrl(AUDIO_TO_TEXT_ENDPOINT))
                .post(body)
                .addHeader("Authorization", config.getAuthorizationHeader())
                .build();
        
        try (Response response = httpClient.newCall(request).execute()) {
            return handleResponse(response, TextResponse.class);
        } catch (IOException e) {
            throw new DifyException("Failed to convert audio to text", e);
        }
    }
    
    /**
     * 语音转文本（通过字节数组）
     * 
     * @param audioData 音频数据
     * @param fileName 文件名
     * @param user 用户标识
     * @return 文本响应
     * @throws DifyException 如果请求失败
     */
    public TextResponse audioToText(byte[] audioData, String fileName, String user) throws DifyException {
        MultipartBody body = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", fileName,
                        RequestBody.create(audioData, MediaType.parse("audio/*")))
                .addFormDataPart("user", user)
                .build();
        
        Request request = new Request.Builder()
                .url(config.getFullUrl(AUDIO_TO_TEXT_ENDPOINT))
                .post(body)
                .addHeader("Authorization", config.getAuthorizationHeader())
                .build();
        
        try (Response response = httpClient.newCall(request).execute()) {
            return handleResponse(response, TextResponse.class);
        } catch (IOException e) {
            throw new DifyException("Failed to convert audio to text", e);
        }
    }
    
    /**
     * 获取支持的语音列表
     * 
     * @return 语音列表响应
     * @throws DifyException 如果请求失败
     */
    public VoicesResponse getSupportedVoices() throws DifyException {
        Request request = new Request.Builder()
                .url(config.getFullUrl("voices"))
                .get()
                .addHeader("Authorization", config.getAuthorizationHeader())
                .build();
        
        try (Response response = httpClient.newCall(request).execute()) {
            return handleResponse(response, VoicesResponse.class);
        } catch (IOException e) {
            throw new DifyException("Failed to get supported voices", e);
        }
    }
    
    /**
     * 获取支持的音频格式
     * 
     * @return 音频格式响应
     * @throws DifyException 如果请求失败
     */
    public AudioFormatsResponse getSupportedAudioFormats() throws DifyException {
        Request request = new Request.Builder()
                .url(config.getFullUrl("audio-formats"))
                .get()
                .addHeader("Authorization", config.getAuthorizationHeader())
                .build();
        
        try (Response response = httpClient.newCall(request).execute()) {
            return handleResponse(response, AudioFormatsResponse.class);
        } catch (IOException e) {
            throw new DifyException("Failed to get supported audio formats", e);
        }
    }
    
    // 内部响应类定义
    public static class AudioResponse {
        private String taskId;
        private String audioUrl;
        private byte[] audioData;
        private String format;
        private Integer duration;
        
        // Getter和Setter方法
        public String getTaskId() {
            return taskId;
        }
        
        public void setTaskId(String taskId) {
            this.taskId = taskId;
        }
        
        public String getAudioUrl() {
            return audioUrl;
        }
        
        public void setAudioUrl(String audioUrl) {
            this.audioUrl = audioUrl;
        }
        
        public byte[] getAudioData() {
            return audioData;
        }
        
        public void setAudioData(byte[] audioData) {
            this.audioData = audioData;
        }
        
        public String getFormat() {
            return format;
        }
        
        public void setFormat(String format) {
            this.format = format;
        }
        
        public Integer getDuration() {
            return duration;
        }
        
        public void setDuration(Integer duration) {
            this.duration = duration;
        }
    }
    
    public static class TextResponse {
        private String text;
        private String language;
        private Double confidence;
        private Integer duration;
        
        // Getter和Setter方法
        public String getText() {
            return text;
        }
        
        public void setText(String text) {
            this.text = text;
        }
        
        public String getLanguage() {
            return language;
        }
        
        public void setLanguage(String language) {
            this.language = language;
        }
        
        public Double getConfidence() {
            return confidence;
        }
        
        public void setConfidence(Double confidence) {
            this.confidence = confidence;
        }
        
        public Integer getDuration() {
            return duration;
        }
        
        public void setDuration(Integer duration) {
            this.duration = duration;
        }
    }
    
    public static class VoicesResponse {
        // 根据实际API响应结构定义字段
    }
    
    public static class AudioFormatsResponse {
        // 根据实际API响应结构定义字段
    }
}